<template>
  <!-- 属性面板 -->
  <div> <!-- 移除外层的 v-if=\"activeRightTab === \'properties\'\" -->
    <h4 class="prop-title">对象属性</h4>

    <div v-if="selectedObject">
        <!-- 位置 -->
        <div class="prop-group">
            <label>位置</label>
            <div class="prop-row">
                <div class="prop-sub-label">X</div> <input type="number" v-model.number="selectedObject.left" @change="requestRenderProp">
                <div class="prop-sub-label">Y</div> <input type="number" v-model.number="selectedObject.top" @change="requestRenderProp">
            </div>
        </div>
        <!-- 尺寸 -->
        <div class="prop-group">
            <label>尺寸</label>
            <div class="prop-row">
                <div class="prop-sub-label">W</div> <input type="number" v-model.number="selectedObject.width" @change="handleWidthChange" :disabled="selectedObject.lockScalingX">
                <div class="prop-sub-label">H</div> <input type="number" v-model.number="selectedObject.height" @change="handleHeightChange" :disabled="selectedObject.lockScalingY">
            </div>
        </div>
        <!-- 旋转与透明度 -->
        <div class="prop-group">
            <label>旋转</label>
            <div class="prop-row">
                <input type="number" v-model.number="selectedObject.angle" @change="requestRenderProp" style="width: 70px;"> °
            </div>
        </div>
        <div class="prop-group">
            <label>透明度</label>
            <div class="prop-row">
                <input 
                  type="range" 
                  min="0" 
                  max="1" 
                  step="0.01" 
                  :value="selectedObject.opacity ?? 1" 
                  @input="handleOpacityInput" 
                  style="width: 120px; vertical-align: middle;"
                >
                <span style="margin-left: 10px;">{{ Math.round((selectedObject.opacity ?? 1) * 100) }}%</span>
            </div>
        </div>

        <!-- 外观 -->
        <h4 class="prop-subtitle">外观</h4>
        <!-- 填充 -->
        <div class="prop-group">
            <label>填充</label>
            <input type="color" v-model="selectedObject.fill" @input="requestRenderProp" :disabled="!hasProperty(selectedObject, 'fill')">
        </div>
        <!-- 描边 -->
        <div class="prop-group">
            <label>描边</label>
            <div class="prop-row stroke-row">
                <input type="color" v-model="selectedObject.stroke" @input="requestRenderProp" :disabled="!hasProperty(selectedObject, 'stroke')">
                <input type="number" min="0" v-model.number="selectedObject.strokeWidth" @change="requestRenderProp" style="width: 60px; margin-left: 10px;" :disabled="!hasProperty(selectedObject, 'strokeWidth')">
                <span style="margin-left: 5px;">px</span>
            </div>
        </div>
        <!-- 圆角 (仅矩形显示) -->
        <div class="prop-group" v-if="selectedObject.type === 'rect'">
            <label>圆角</label>
            <input type="number" min="0" v-model.number="selectedObject.rx" @change="syncRy(); requestRenderProp()" style="width: 70px;"> px
        </div>
        <!-- 阴影 -->
        <div class="prop-group">
            <label>阴影</label>
            <input type="checkbox" :checked="!!selectedObject.shadow" @change="toggleShadow">
        </div>
        <div v-if="selectedObject && selectedObject.shadow">
            <div class="prop-group indent">
                <label>颜色</label>
                <input type="color" v-model="selectedObject.shadow.color" @input="requestRenderProp">
            </div>
            <div class="prop-group indent">
                <label>模糊</label>
                <input type="number" min="0" v-model.number="selectedObject.shadow.blur" @change="requestRenderProp" style="width: 70px;"> px
            </div>
            <div class="prop-group indent">
                <label>偏移X</label>
                <input type="number" v-model.number="selectedObject.shadow.offsetX" @change="requestRenderProp" style="width: 70px;"> px
            </div>
            <div class="prop-group indent">
                <label>偏移Y</label>
                <input type="number" v-model.number="selectedObject.shadow.offsetY" @change="requestRenderProp" style="width: 70px;"> px
            </div>
        </div>

        <!-- 文字专属属性 (当选中文字时显示) -->
        <div v-if="selectedObject.type === 'i-text'">
            <h4 class="prop-subtitle">文字属性</h4>
            <!-- 文本内容 -->
            <div class="prop-group">
                <label>文字</label>
                <textarea
                  v-model="selectedObject.text"
                  @input="handleTextInput"
                  rows="3"
                  class="prop-textarea"></textarea>
            </div>
            <!-- 字体族 -->
            <div class="prop-group">
                <label>字体</label>
                <select v-model="selectedObject.fontFamily" @change="syncFontFamily(); requestRenderProp()" class="prop-select">
                    <option value="Arial">Arial</option>
                    <option value="Times New Roman">Times New Roman</option>
                    <option value="微软雅黑">微软雅黑</option>
                    <option value="宋体">宋体</option>
                    <option value="黑体">黑体</option>
                </select>
            </div>
            <!-- 字号 -->
            <div class="prop-group">
                <label>字号</label>
                <div class="prop-row">
                    <input type="number" min="1" v-model.number="selectedObject.fontSize" @change="syncFontSize(); requestRenderProp()" style="width: 80px;"> px
                </div>
            </div>
            <!-- 样式 -->
            <div class="prop-group">
                <label>样式</label>
                <div class="prop-row button-group">
                    <button :class="{ active: selectedObject.fontWeight === 'bold' }" @click="toggleTextStyle('fontWeight', 'bold', 'normal')">B</button>
                    <button :class="{ active: selectedObject.fontStyle === 'italic' }" @click="toggleTextStyle('fontStyle', 'italic', 'normal')">I</button>
                    <button :class="{ active: selectedObject.underline === true }" @click="toggleTextStyle('underline', true, false)">U</button>
                </div>
            </div>
        </div> <!-- 结束 文字专属属性 v-if -->

    </div> <!-- 结束 v-if="selectedObject" -->

    <div v-else class="prop-empty">
        <p>未选择对象</p>
        <p class="tip">请在画布上选择一个对象以编辑其属性</p>
    </div>

  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed, defineProps, defineEmits } from 'vue'; // 引入 defineProps, defineEmits
// @ts-ignore - Fabric 类型问题
import { fabric } from 'fabric';

// --- Props ---
const props = defineProps<{
  selectedObject: any | null; // Fabric 对象类型复杂，暂时用 any
  requestRenderProp: () => void; // 接收父组件的渲染请求函数
}>();

// --- Emits ---
const emit = defineEmits(['update:text-settings']); // 定义事件

// --- 辅助函数 ---
function hasProperty(obj: any, prop: string): boolean {
  // 确保 obj 不是 null 或 undefined，并且是对象类型
  if (!obj || typeof obj !== 'object') {
    return false;
  }
  // 对于 Fabric 对象，直接检查属性是否存在可能不够，因为它们可能在原型链上
  // 或者使用 get 方法更可靠
  // return obj.hasOwnProperty(prop);
  // 尝试使用 Fabric 的 get 方法
   if (typeof obj.get === 'function') {
     try {
       // 对于 fill 和 stroke，它们可能是 Gradient 对象，不是简单类型
       if (prop === 'fill' || prop === 'stroke') return true; // 假设它们总是可以设置
       // 对于 shadow，检查它是否存在且不为 null
       if (prop === 'shadow') return obj.shadow !== null && typeof obj.shadow === 'object';
       // 对于 strokeWidth，需要特殊处理，因为 0 也是有效值
       if (prop === 'strokeWidth') return typeof obj.get(prop) === 'number';

       return obj.get(prop) !== undefined;
     } catch (e) {
       // 如果 get 方法不存在或出错，回退到 hasOwnProperty
       return Object.prototype.hasOwnProperty.call(obj, prop);
     }
   }
   // 如果没有 get 方法，使用 hasOwnProperty
   return Object.prototype.hasOwnProperty.call(obj, prop);
}


// --- 属性处理函数 ---

// 处理文本输入
function handleTextInput(event: Event) {
  if (props.selectedObject && props.selectedObject.type === 'i-text') {
    // Fabric IText 对象在 text 属性变化时可能需要手动更新边界框
    props.selectedObject.initDimensions();
    props.requestRenderProp();
  }
}

// 处理宽度输入变化
function handleWidthChange(event: Event) {
   if (props.selectedObject) {
    // 注意：直接修改 width/height 可能会扭曲对象，通常应该修改 scaleX/scaleY
    // 这里暂时只触发渲染，复杂的缩放逻辑可以在父组件或更专门的函数中处理
    props.requestRenderProp();
  }
}

// 处理高度输入变化
function handleHeightChange(event: Event) {
   if (props.selectedObject) {
    props.requestRenderProp();
  }
}

// 同步矩形圆角 ry
function syncRy() {
  if (props.selectedObject && props.selectedObject.type === 'rect') {
    // 确保 rx 是数字
    const rxValue = Number(props.selectedObject.rx);
    if (!isNaN(rxValue)) {
        props.selectedObject.set('ry', rxValue); // 使用 set 方法
        props.requestRenderProp();
    }
  }
}

// 切换阴影
function toggleShadow(event: Event) {
  if (!props.selectedObject) return;

  const target = event.target as HTMLInputElement;
  let shadowValue: fabric.Shadow | null = null; // 显式声明类型

  if (target.checked) {
    // 启用阴影，设置默认值（如果不存在）
    // 直接访问 shadow 可能为 null，需要判断
    const currentShadow = props.selectedObject.shadow as fabric.Shadow | null;
    if (!currentShadow) {
        shadowValue = new fabric.Shadow({ // 创建新实例
          color: 'rgba(0,0,0,0.5)',
          blur: 5,
          offsetX: 5,
          offsetY: 5
        });
    } else {
        // 如果已有阴影对象，则保持不变（因为复选框只是切换显示/隐藏）
        // 或者可以考虑如果之前是 null，则恢复上一次的值？这里简单处理，如果存在就不变
        shadowValue = currentShadow;
    }
  } else {
    // 禁用阴影
    shadowValue = null;
  }
  // 使用 set 方法更新阴影
  props.selectedObject.set('shadow', shadowValue);
  props.requestRenderProp();
}

// 同步左侧文字面板 (通过 emit)
function syncLeftTextPanel(target: any) {
    emit('update:text-settings', {
        fontFamily: target.fontFamily || 'Arial',
        fontSize: target.fontSize || 24,
        color: target.fill || '#333333'
        // 可以传递更多状态
    });
}

// 当右侧字体选择变化时，同步左侧
function syncFontFamily() {
  if (props.selectedObject && props.selectedObject.type === 'i-text') {
     syncLeftTextPanel(props.selectedObject);
     // 直接修改 prop 是不推荐的，但 Fabric 对象通常允许
     // props.requestRenderProp(); // select 的 @change 会触发
  }
}

// 当右侧字号变化时，同步左侧
function syncFontSize() {
  if (props.selectedObject && props.selectedObject.type === 'i-text') {
     syncLeftTextPanel(props.selectedObject);
     // props.requestRenderProp(); // input 的 @change 会触发
  }
}

// 切换文字样式 (粗体、斜体、下划线)
function toggleTextStyle(prop: string, activeValue: any, inactiveValue: any) {
  if (!props.selectedObject || props.selectedObject.type !== 'i-text') return;

  const currentValue = props.selectedObject.get(prop);
  props.selectedObject.set(prop, currentValue === activeValue ? inactiveValue : activeValue);
  props.requestRenderProp();
  // 样式变化也可能需要同步左侧面板，但目前左侧没有对应控件
}

// 新增：手动处理透明度输入
function handleOpacityInput(event: Event) {
  if (!props.selectedObject) return;
  
  const target = event.target as HTMLInputElement;
  const value = parseFloat(target.value); // 显式转换为浮点数
  
  if (!isNaN(value)) {
    console.log(`PropertiesPanel: Updating opacity to (number):`, value); // 添加日志
    props.selectedObject.set('opacity', value); // 使用 set 方法更新
    props.requestRenderProp(); // 请求重新渲染
  } else {
    console.warn('PropertiesPanel: Invalid opacity value received:', target.value);
  }
}

// --- Watchers (可选，用于响应 prop 变化) ---
watch(() => props.selectedObject, (newVal, oldVal) => {
  console.log('PropertiesPanel: selectedObject changed', newVal);
  // 可以在这里做一些对象变化时的清理或初始化工作，但要小心无限循环
});

</script>

<style scoped>
/* 属性面板内的通用样式 */
.prop-title {
  font-size: 16px;
  margin-bottom: 15px;
  color: #333;
  font-weight: 500;
}

.prop-group {
  margin-bottom: 12px;
  font-size: 13px;
}

.prop-group label {
  display: inline-block; /* 改为 inline-block 以便与输入控件同行 */
  width: 50px;
  color: #666;
  margin-right: 8px; /* 增加右边距 */
  vertical-align: middle; /* 垂直居中对齐 */
}

.prop-row {
  display: flex;
  align-items: center;
  gap: 5px;
}

.prop-sub-label {
  width: 20px;
  text-align: right;
  font-size: 12px;
  color: #888;
}

input[type="number"],
input[type="range"],
select.prop-select,
textarea.prop-textarea {
  padding: 4px 8px; /* 统一内边距 */
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 13px;
  box-sizing: border-box; /* 确保 padding 不会撑大元素 */
}

input[type="number"] {
  width: 70px; /* 稍微加宽 */
}
input[type="color"] {
  vertical-align: middle;
  width: 28px; /* 调整颜色选择器大小 */
  height: 28px;
  padding: 2px;
  border: 1px solid #ccc; /* 添加边框 */
  border-radius: 4px;
  cursor: pointer;
}

input[type="range"] {
  width: 120px;
  vertical-align: middle;
}

/* 属性面板内的子标题 */
.prop-subtitle {
  font-size: 14px;
  font-weight: 500;
  color: #555;
  margin-top: 20px; /* 增加与上一组的距离 */
  margin-bottom: 12px; /* 调整下方距离 */
  padding-bottom: 6px; /* 调整下方内边距 */
  border-bottom: 1px solid #eee;
}

/* 下拉选择框样式 */
.prop-select {
  width: calc(100% - 60px); /* 留出标签宽度 */
  height: 30px;
  display: inline-block; /* 改为 inline-block */
  vertical-align: middle;
}

/* 按钮组样式 */
.button-group {
  display: inline-flex; /* 改为 inline-flex */
  vertical-align: middle;
}

.button-group button {
  min-width: 30px;
  height: 30px;
  padding: 0 8px;
  margin-right: 5px;
  border: 1px solid #ccc;
  background-color: #fff;
  border-radius: 4px;
  cursor: pointer;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.button-group button:hover {
  background-color: #f0f0f0;
  border-color: #bbb;
}

.button-group button.active {
  background-color: #e0e0e0;
  border-color: #aaa;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
}

.button-group button i {
  font-size: 14px;
}

/* 描边行样式 */
.stroke-row input[type="color"] {
  flex-shrink: 0;
}
.stroke-row input[type="number"] {
   margin-left: 8px; /* 微调间距 */
}
.stroke-row span {
  margin-left: 3px; /* 微调间距 */
}


/* 圆角和阴影组缩进 */
.prop-group.indent {
  padding-left: 20px;
}

.prop-group.indent label {
  width: 40px;
}

/* 阴影复选框样式 */
/* .prop-group input[type="checkbox"] { */
/* 移除特定样式，让它和标签对齐 */
/* } */

/* 文本区域样式 */
.prop-textarea {
  width: calc(100% - 60px); /* 留出标签宽度 */
  resize: vertical;
  display: inline-block; /* 改为 inline-block */
  vertical-align: top; /* 顶部对齐 */
}

/* 空状态提示 */
.prop-empty {
  text-align: center;
  padding: 30px 15px;
  color: #999;
}

.prop-empty .tip {
  font-size: 12px;
  margin-top: 10px;
  color: #aaa;
}

</style>